package fr.licpro.filebox.activity;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import fr.licpro.filebox.R;
import fr.licpro.filebox.activity.fragments.DetailFragment;
import fr.licpro.filebox.activity.fragments.FileboxListFragment;
import fr.licpro.filebox.dto.enums.FileTypeEnum;
import fr.licpro.filebox.model.Content;
import fr.licpro.filebox.model.File;
import fr.licpro.filebox.service.SyncService;
import fr.licpro.filebox.service.sync.FilesSync;
import fr.licpro.filebox.utils.AccountInformation;
import fr.licpro.filebox.utils.FileCache;

/**
 * List Activity to contain a fragment details for a file.
 * @author Abdessamad EL FATTAKE
 * @author Sylvain LE GOUELLEC
 * @version 1.0.0
 * @since 1.0.0
 */
public class ListActivity extends Activity 
{
	/**
	 * Know if receiver was already called
	 */
	private boolean receiverCalled = false;
	
	/**
	 * True if the Add contact menu has to be shown
	 */
	private boolean mVcardOptionMenu = false;
	
	/**
	 * Fragment contains file detail
	 */
	private DetailFragment mDetailFragment;

	/**
	 * Broadcast receiver which listen changes of connectivity state
	 */
	private ConnectivityReceiver mReceiver;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_list);
		
		getActionBar().setDisplayHomeAsUpEnabled(true);
		  
		Fragment frag = getFragmentManager().findFragmentById(R.id.items_list);
		FileboxListFragment frag2 = (FileboxListFragment) getFragmentManager().findFragmentByTag("LIST_FRAGMENT");
		
		mDetailFragment = (DetailFragment) getFragmentManager().findFragmentById(R.id.item_detail);
		if(mDetailFragment == null)
			mDetailFragment = (DetailFragment) getFragmentManager().findFragmentByTag("DETAIL_FRAGMENT");
		
		// If frag is null, it's a smartphone
		// If frag2 is null, is the first time that the ListFragment is created
		if(frag == null && frag2 == null)
		{
			FileboxListFragment listFragment = new FileboxListFragment();
			
			FragmentTransaction transaction = getFragmentManager().beginTransaction();
			transaction.add(R.id.fragment_container, listFragment,"LIST_FRAGMENT").commit();
		}
	}
	
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		FileboxListFragment listFragment = (FileboxListFragment) getFragmentManager().findFragmentByTag("LIST_FRAGMENT");
		
		if(listFragment != null && listFragment.isOnBackStack())
		{
			ArrayList<File> files = listFragment.getFiles();
			
			outState.putParcelableArrayList("FILES", files);
		}
		super.onSaveInstanceState(outState);
	}
	
	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		FileboxListFragment listFragment = (FileboxListFragment) getFragmentManager().findFragmentByTag("LIST_FRAGMENT");
		
		if(listFragment != null)
		{
			if(savedInstanceState.containsKey("FILES"))
			{
				ArrayList<File> files = savedInstanceState.getParcelableArrayList("FILES");
				
				listFragment.restoreFiles(files);
				listFragment.setOnBackStack(true);
			}
		}
		super.onRestoreInstanceState(savedInstanceState);
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.list, menu);
		
		MenuItem item = menu.findItem(R.id.add_to_contacts);
		
		if(item != null && mVcardOptionMenu)
		{
			item.setVisible(true);
		}
				
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.

		switch (item.getItemId()) 
		{
			case R.id.add_to_contacts: 
				mDetailFragment.addContact();
				break;
				
			case R.id.action_profil:
				if(SyncService.isNetworkAvailable(this))
				{
					openProfilActivity();
				}
				else
				{
					Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
				}
				break;
				
			case android.R.id.home:
				onBackPressed();
				break;
				
			default:
				break;
		}
		
		return super.onOptionsItemSelected(item);
	}
	
	/**
	 * Launch activity to display AccountActivity
	 */
	private void openProfilActivity() {
		Intent intent = new Intent(getApplicationContext(), AccountActivity.class);
		startActivity(intent);		
	}
	
	/**
	 * Launch activity to log
	 */
	private void openConnectionActivity(){
		Intent intent = new Intent(getApplicationContext(), MainActivity.class);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
		startActivity(intent);
	}

	@Override
	public void onBackPressed() {
		
		FileboxListFragment listFragment = (FileboxListFragment) getFragmentManager().findFragmentByTag("LIST_FRAGMENT");
	
		if(listFragment != null && !listFragment.isOnBackStack())
		{
			if(!listFragment.goToParent())
				super.onBackPressed();
		}
		else
			super.onBackPressed();
	}
	
	/**
	 * If application is on smartphone, current fragment is replaced by fragment detail.
	 * @param content File's content
	 */
	public void showDetailsFragment(FileboxListFragment fileboxFragment, Content content) 
	{
		FileCache cache = new FileCache(this);
		
		java.io.File file = cache.getFile(content.getHashID());
		
		if(content.getMimeType().contains(FileTypeEnum.PDF.getMimeType()))
		{			
			Intent intent = new Intent(Intent.ACTION_VIEW);
			
			intent.setDataAndType(Uri.fromFile(file),"application/pdf");
			
			PackageManager packageManager = getPackageManager();
			List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
			if(activities.size() > 0)
			{
				startActivity(intent);
			}
			else
			{
				Intent intentMarket = new Intent(Intent.ACTION_VIEW);
				intentMarket.setData(Uri.parse("market://search?q=pdf&c=apps"));
				startActivity(intentMarket);
			}
			
			fileboxFragment.disableLoadLayout(true);
		}
		else if(content.getMimeType().contains(FileTypeEnum.MP3.getMimeType()))
		{
			Intent intent = new Intent(Intent.ACTION_VIEW);
			intent.setDataAndType(Uri.fromFile(file),"audio/*");
			startActivity(intent);
			
			fileboxFragment.disableLoadLayout(true);
		}
		else
		{
			DetailFragment frag = (DetailFragment) getFragmentManager().findFragmentById(R.id.item_detail);
			
			// If its's null, so it's a smartphone. We have to replace actual fragment by details fragment
			if(frag == null)
			{
				mDetailFragment = new DetailFragment();
				
				Bundle args = new Bundle();
				args.putParcelable(FilesSync.FILE_CONTENT, content);
				mDetailFragment.setArguments(args);
				
				FragmentTransaction transaction = getFragmentManager().beginTransaction();
			
				transaction.replace(R.id.fragment_container, mDetailFragment,"DETAIL_FRAGMENT");
				transaction.addToBackStack(null);
				
				transaction.commit();
			}
			else
			{
				mDetailFragment = frag;
				mDetailFragment.setContent(content);
				fileboxFragment.disableLoadLayout(true);
			}
		}
	}
	
	/**
	 * Permit to know if option menu to add a contact is showed
	 * @param show	boolean
	 */
	public void showVcardOptionMenu(boolean show)
	{
		mVcardOptionMenu = show;
	}
	
	/**
	 * Broadcast receiver which listen changes of connectivity state
	 */
	private class ConnectivityReceiver extends BroadcastReceiver
	{
		@Override
		public void onReceive(Context arg0, Intent intent) 
		{
			if(intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION))
			{
				boolean disconnected = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
				
				if(!disconnected && AccountInformation.getInstance().getToken() == null && !receiverCalled)
				{
					receiverCalled = true;
					openConnectionActivity();
					Toast.makeText(getApplicationContext(), R.string.connection_available, Toast.LENGTH_LONG).show();
				}
			}
		}
	}
	
	@Override
	protected void onStart() {
		mReceiver = new ConnectivityReceiver();
		registerReceiver(mReceiver,new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
		super.onStart();
	}
	
	@Override
	protected void onStop() {
		if(mReceiver != null)
			unregisterReceiver(mReceiver);
		super.onStop();
	}
}
